﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.EntityClient;
using Microsoft.TeamFoundation.Client;
using System.Net;

namespace TeamFoundation.ContinuousMerge
{
    /// <summary>
    /// Represents the runtime configuration.
    /// </summary>
    public class RuntimeConfiguration : ObjectCache
    {
        /// <summary>
        /// The connection string.
        /// </summary>
        private string _connectionString;

        /// <summary>
        /// The configuration data.
        /// </summary>
        private Dictionary<string, string> _configurationData = new Dictionary<string,string>();

        /// <summary>
        /// Gets a configuration value.
        /// </summary>
        /// <param name="key">The configuration value.</param>
        public string this[string key]
        {
            get
            {
                if (key == "ConnectionString")
                    return _connectionString;

                string result;
                _configurationData.TryGetValue(key, out result);
                return result;
            }
        }

        /// <summary>
        /// Sets a configuration value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public RuntimeConfiguration SetConfiguration(string key, string value)
        {
            var result = new RuntimeConfiguration();
            result._connectionString = _connectionString;
            result._configurationData = new Dictionary<string, string>(_configurationData);

            if (key == "ConnectionString")
            {
                result._connectionString = value;
            }
            else
            {
                if (result._configurationData.ContainsKey(key))
                {
                    result._configurationData[key] = value;
                }
                else
                {
                    result._configurationData.Add(key, value);
                }
            }
            return result;
        }

        /// <summary>
        /// Refreshes the runtime configuration.
        /// </summary>
        public RuntimeConfiguration Refresh()
        {
            RuntimeConfiguration result = new RuntimeConfiguration();
            result._connectionString = _connectionString;

            using (var db = GetDatabase())
            {
                var entries = from a in db.ConfigurationEntries
                              select a;
                foreach (var entry in entries)
                {
                    result._configurationData.Add(entry.Name, entry.Value);
                }
            }

            return result;
        }
        
        /// <summary>
        /// Saves the runtime configuration.
        /// </summary>
        public void Save()
        {
            using (var db = GetDatabase())
            {
                foreach (KeyValuePair<string, string> kvp in _configurationData)
                {
                    var entry = (from a in db.ConfigurationEntries
                                where a.Name == kvp.Key
                                select a).FirstOrDefault();
                    if (entry == null)
                    {
                        entry = Model.ConfigurationEntry.CreateConfigurationEntry(kvp.Key, kvp.Value);
                        db.AddToConfigurationEntries(entry);
                    }
                    entry.Value = kvp.Value;
                    db.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Gets an initialized instance of the <see cref="Model.Database"/>.
        /// </summary>
        public Model.Database GetDatabase()
        {
            return new TeamFoundation.ContinuousMerge.Model.Database(_connectionString.BuildEntityConnectionString());
        }

        
    }
}
